package com.example.gravitysituation;

import java.util.Random;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.os.Bundle;
import android.text.Editable;
import android.text.method.DigitsKeyListener;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.PopupMenu;
import android.widget.TextView;

public class CircuitSimulation extends Activity {

	public static Integer goal = 0; 
	public Integer circuitNum;
	public Integer goalComponent;
	public Integer circuitComponents;
	public Circuit circuit;
	public Component component = new Component();
	public double valueDouble = 0;
	public Editable voltage;
	public Editable value;
	public String componentType;
	
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
	    
	    Bundle extras = getIntent().getExtras();
	    circuitNum = extras.getInt("CircuitNum");
	    
	    // Launch appropriate circuit layout and initialize circuit
	    switch(circuitNum){
        	case 1:
	                setContentView(R.layout.circuit1);
	                circuitComponents = 1;
	                circuit = new Circuit(circuitComponents);
	                break;
	        case 2:
	                setContentView(R.layout.circuit2);
	                circuitComponents = 2;
	                circuit = new Circuit(circuitComponents);
	                break;
	        case 3:
	                setContentView(R.layout.circuit3);
	                circuitComponents = 2;
	                circuit = new Circuit(circuitComponents);
	                break;
	        case 4:
	                setContentView(R.layout.circuit4);
	                circuitComponents = 3;
	                circuit = new Circuit(circuitComponents);
	                break;
	    }	
	}
	
	@Override
	// Generate goal current goal for circuit
	public boolean onCreateOptionsMenu(Menu menu) {
	    getMenuInflater().inflate(R.menu.circuit_simulation, menu);
	    goal = newGoal();
	    return true;
	}
	
	
	// Prompt user information about selected component and add to circuit
	public void addComponent(View v) {
		component = new Component();
	    final View view = v;
	    final int id  = v.getId();
	    
	    // Pop-up menu for component options
	    PopupMenu popup = new PopupMenu(this, v);	    
	    MenuInflater inflater = popup.getMenuInflater();
	    inflater.inflate(R.menu.component_popup_menu, popup.getMenu());
	    popup.show();
	    popup.setOnMenuItemClickListener(
	    new PopupMenu.OnMenuItemClickListener() {
	    	
        @Override
        public boolean onMenuItemClick(MenuItem item) {
            
            Button myButton = (Button) findViewById(id);
            switch (item.getItemId()){                      
            case R.id.Resistor:
                    myButton.setText("R");
                    componentType = "resistor";
                    break;
            case R.id.Capacitor:
                    myButton.setText("C");
                    componentType = "capacitor";
                    break;
            case R.id.Inductor:
                    myButton.setText("L");
                    componentType = "inductor";                                     
                    break;
                                    
            }
            // Set Component Type and prompt value through alert
            component.setType(componentType);
            promptValue(view , id);
                    return true;
        }
	    });            
	}
	
	// Display an alert box to prompt value
	public void promptValue(View v, int id){
	    final Button myButton = (Button) findViewById(id);
	    AlertDialog.Builder alert = new AlertDialog.Builder(this);
	    alert.setTitle("ValuePrompt");
	    alert.setMessage("Input a value:");           
	    
	    final EditText input = new EditText(this);
	    input.setKeyListener(DigitsKeyListener.getInstance());
	    alert.setView(input);
	    
	    // On valid input set appropriate component value 
	    alert.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
	    public void onClick(DialogInterface dialog, int whichButton) {
	    	value = input.getText();
	    	component.setValue(Double.parseDouble(value.toString()));
	    	myButton.setText(myButton.getText() + ":" + value);
	    	int componentNum = 0;
	    	switch(myButton.getId()){
	            case R.id.component1:
                    componentNum = 1;
                    break;
	            case R.id.component2:
                    componentNum = 2;
                    break;
	            case R.id.component3:
                    componentNum = 3;
                    break;
	    	}       
	                             
	        // Add component to circuit      
	    	String type = component.getType();
	    	double val =component.getValue();
	    	circuit.addComponent(type,val, componentNum);
    	}
	    });
	
	    // On Cancel do nothing 
	    alert.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
	    public void onClick(DialogInterface dialog, int whichButton) {
	                // Canceled.
	    }
        });
	
        alert.show();
	}
	
    // Voltage Input
	public void promptVoltage(View v){
		AlertDialog.Builder alert = new AlertDialog.Builder(this);
	    alert.setTitle("VoltagePrompt");
	    alert.setMessage("Input a voltage:");           
	
		final EditText input = new EditText(this);
		input.setKeyListener(DigitsKeyListener.getInstance());
		alert.setView(input);
		
		// On valid set circuit voltage and display
		alert.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
	    public void onClick(DialogInterface dialog, int whichButton) {
	    	voltage = input.getText();
	    	TextView voltageView = (TextView) findViewById(R.id.voltageValue);
	    	voltageView.setText("V:" + voltage);
	    	circuit.setVoltage(Double.parseDouble(voltage.toString()));
	    }
		});
		
		// On cancel do nothing
		alert.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
		public void onClick(DialogInterface dialog, int whichButton) {
	            // Canceled.
		}
        });
	
	    alert.show();
	}
	    
	// Evaluate current for a given component
    public void calculateCurrent(View v){
    	if(circuit.valid()){
    		double voltageVal = Double.parseDouble(voltage.toString());
    		switch(circuitNum){
    			case 1:
                    String cmpOneType = circuit.getComponent(1).getType();
                    double cmpOneValue = circuit.getComponent(1).getValue();
                    if (cmpOneType == "resistor")
                    	updateStats( voltageVal/cmpOneValue);     
                    else 
                    	reportError();
                    break;
                case 2:
                    cmpOneType = circuit.getComponent(1).getType();
                    cmpOneValue = circuit.getComponent(1).getValue();
                    String cmpTwoType = circuit.getComponent(2).getType();
                    double cmpTwoValue = circuit.getComponent(2).getValue();
                    if (cmpOneType == "resistor" && cmpTwoType == "resistor"){
                    	circuit.getComponent(1).setCurrent(voltageVal/(cmpOneValue+cmpTwoValue));
                    	circuit.getComponent(2).setCurrent(voltageVal/(cmpOneValue+cmpTwoValue));
                    }
                    else if (cmpOneType == "resistor"){
                    	circuit.getComponent(1).setCurrent(voltageVal/(cmpOneValue));
                    	circuit.getComponent(2).setCurrent(voltageVal/(cmpOneValue));
                    } 
                    else if (cmpTwoType == "resistor"){
                    	circuit.getComponent(1).setCurrent(voltageVal/(cmpOneValue));
                    	circuit.getComponent(2).setCurrent(voltageVal/(cmpOneValue));
                    }
                    else 
                    	reportError();
                    updateStats(circuit.getComponent(goalComponent).getCurrent());
                    break;
                case 3:
                    cmpOneType = circuit.getComponent(1).getType();
                    cmpOneValue = circuit.getComponent(1).getValue();
                    cmpTwoType = circuit.getComponent(2).getType();
                    cmpTwoValue = circuit.getComponent(2).getValue();
                    if (cmpOneType == "resistor" && cmpTwoType == "resistor"){
                    	circuit.getComponent(1).setCurrent(voltageVal/cmpOneValue);
                    	circuit.getComponent(2).setCurrent(voltageVal/cmpTwoValue);
                    }
                    else 
                    	reportError();
                    updateStats(circuit.getComponent(goalComponent).getCurrent());
                    break;
                case 4:
                    cmpOneType = circuit.getComponent(1).getType();
                    cmpOneValue = circuit.getComponent(1).getValue();
                    cmpTwoType = circuit.getComponent(2).getType();
                    cmpTwoValue = circuit.getComponent(2).getValue();
                    String cmpThreeType = circuit.getComponent(3).getType();
                    double cmpThreeValue = circuit.getComponent(3).getValue(); 
                    if (cmpOneType == "resistor" && cmpTwoType == "resistor" && cmpThreeType == "resistor"){
                    	double Req = cmpOneValue + 1/(1/cmpTwoValue + 1/cmpThreeValue);
                    	double Ieq = voltageVal/Req;
                    	double volBranch = voltageVal-cmpOneValue*Ieq;
                    	circuit.getComponent(1).setCurrent(Ieq);
                    	circuit.getComponent(2).setCurrent(volBranch/cmpTwoValue);
                    	circuit.getComponent(3).setCurrent(volBranch/cmpThreeValue);
                    }
                    else if (cmpOneType == "resistor" && cmpTwoType == "resistor"){
                    	double Req = cmpOneValue + 1/(1/cmpTwoValue);
                    	double Ieq = voltageVal/Req;
                    	double volBranch = voltageVal-cmpOneValue*Ieq;
                    	circuit.getComponent(1).setCurrent(Ieq);
                    	circuit.getComponent(2).setCurrent(volBranch/cmpTwoValue);
                    	circuit.getComponent(3).setCurrent(volBranch/cmpTwoValue);
                    }
                    else if (cmpOneType == "resistor" && cmpThreeType == "resistor"){
                    	double Req = cmpOneValue + 1/(1/cmpThreeValue);
                    	double Ieq = voltageVal/Req;
                    	double volBranch = voltageVal-cmpOneValue*Ieq;
                    	circuit.getComponent(1).setCurrent(Ieq);
                    	circuit.getComponent(2).setCurrent(volBranch/cmpThreeValue);
                    	circuit.getComponent(3).setCurrent(volBranch/cmpThreeValue);
                    }
                    else 
                    	reportError();
                    updateStats(circuit.getComponent(goalComponent).getCurrent());
                    break;
                	
	                        
            }
        }
        else 
        	reportError();                  
	}
	
	// Update text fields for user guess and evaluate if correct
	public void updateStats(double currentGuess){
        TextView currentGuessView = (TextView) findViewById(R.id.currentGuess);
        TextView currentGuessDiff = (TextView) findViewById(R.id.currentDiff);
        
        Double currentDiff = (Double) goal.doubleValue() - currentGuess;
        currentGuessDiff.setText("Guess Error:  " + currentDiff);
        currentGuessView.setText("Current Guessed: " + currentGuess);   
        
        if (Math.abs(currentDiff) < 0.5)
        	correctGuess(); 
	}       
	
	// Dialog box for win conditions
	public void correctGuess(){
		AlertDialog.Builder alert = new AlertDialog.Builder(this);
        alert.setTitle("Correct");
        alert.setMessage("Goal met!");          
	                                
        alert.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
        	public void onClick(DialogInterface dialog, int whichButton) {
        		goal = newGoal(); //generate new goal
        	}
        });
	
        alert.show();           
	}
	
	// Reports error if circuit is invalid
	public void reportError(){
        AlertDialog.Builder alert = new AlertDialog.Builder(this);
        alert.setTitle("ERROR MESAGE");
        alert.setMessage("ERROR: Circuit properties not set or invalid!");              
        
        alert.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
        public void onClick(DialogInterface dialog, int whichButton) {
        }
		});
	
        alert.show();
	}
	
	
	// Generates new current goal 
	public Integer newGoal(){
	Random randomGenerator = new Random();
	goalComponent = randomGenerator.nextInt(circuitComponents)+1;
	goal = randomGenerator.nextInt(25);
	
	TextView currentGoalView = (TextView) findViewById(R.id.currentGoal);
	TextView currentGuessView = (TextView) findViewById(R.id.currentGuess);
	TextView currentDiffView = (TextView) findViewById(R.id.currentDiff);
	
	// Set goal and clear previous guess data
	currentGoalView.setText("Current Goal for Component " + goalComponent.toString() + ": " + goal.toString());
	currentGuessView.setText("");
	currentDiffView.setText("");
	return goal;
	}
	
	
}